#include "qwaveformview.h"
#include "qaudioreader.h"
#include "qaudiorformat.h"
#include "qtimewatch.h"
#include "qmonowaveformdrawing.h"
#include "qstereowaveformdrawing.h"

#include <QFileInfo>
#include <QPainter>
#include <QRect>
#include <QLineF>
#include <QPaintEvent>

namespace AudioUtils {

	class QWaveFormViewPrivate
	{
	public:
		QWaveFormViewPrivate() 
			: leftLineColor(Qt::blue)
			, rightLineColor(Qt::green)
			, backgroundColor(Qt::white)
		{
			init();
		}

		~QWaveFormViewPrivate() 
		{
		}

		void init()
		{
			path = "";
		}

	public:
		QString path;
		QColor leftLineColor;
		QColor rightLineColor;
		QColor backgroundColor;
	};

	QWaveFormView::QWaveFormView(QWidget *parent)
		: QWidget(parent)
		, p(new QWaveFormViewPrivate)
	{
	}

	QWaveFormView::~QWaveFormView()
	{
		delete p;
	}

	void QWaveFormView::open(const QString &path)
	{
		p->path = path;
        update();
    }

	void QWaveFormView::leftLine(const QColor& color)
	{
		p->leftLineColor = color;
	}

	void QWaveFormView::rightLine(const QColor& color)
	{
		p->rightLineColor = color;
	}

	void QWaveFormView::background(const QColor& color)
	{
		p->backgroundColor = color;
	}

	void QWaveFormView::paintEvent(QPaintEvent *event)
	{
		auto rect = this->rect();
		QPainter painter(this);
		painter.fillRect(rect, p->backgroundColor);
		painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);

		if (p->path.isEmpty() || 
			p->path.isNull()
			)
		{
			return;
		}

		QFileInfo file(p->path);
		if (!file.exists())
		{
			p->init();
			return;
		}

		QTimeWatch watch("draw wave:");
		QString path = file.absoluteFilePath();
		QAudioFormat format;
		if (!format.open(path))
		{
			p->init();
			return;
		}

		QAudioReader reader;
		if (!reader.open(path))
		{
			p->init();
			return;
		}

		if (format.mono())
		{
			QMonoWaveformDrawing drawing;
			drawing.setBackGroundColor(p->backgroundColor);
			drawing.setLineColor(p->leftLineColor);
			drawing.draw(painter, format, reader, rect);
		}
		else if (format.stereo())
		{
			QStereoWaveformDrawing drawing;
			drawing.setBackGroundColor(p->backgroundColor);
			drawing.setLeftLineColor(p->leftLineColor);
			drawing.setRightLineColor(p->rightLineColor);
			drawing.draw(painter, format, reader, rect);
		}
    }

}
